// StdAfx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__4AA14050_1B79_4A11_9D24_4E209BF87E2C__INCLUDED_)
#define AFX_STDAFX_H__4AA14050_1B79_4A11_9D24_4E209BF87E2C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <CryModuleDefs.h>
#define eCryModule eCryM_Physics

#undef NO_XENON_INTRINSICS
#define NO_XENON_INTRINSICS
#undef XENON_INTRINSICS


// Enables SPU memory stream debugging 
//#define MEMSTREAM_DEBUG 1
#define MEMSTREAM_DEBUG_TAG (0xcafebabe)

#if defined(MEMSTREAM_DEBUG)
#define MEMSTREAM_DEBUG_ASSERT(x) if (!(x)) { snPause(); }
#else
#define MEMSTREAM_DEBUG_ASSERT(x) 
#endif 

// Enables SPU function table debugging 
//#define ENABLE_SPU_FUNCTABLE_DEBUG 1
// Enable SPU function profiling (currently only intersection jobs) 
//#define ENABLE_SPU_FUNC_PROFILING 1
#define SPU_FUNCTABLE_DEBUG_TAG (0xbaadf00d)

#ifndef PHYSICS_EXPORTS
#define PHYSICS_EXPORTS
#endif

// Entity profiling only possible in non-release builds 
#if !defined(_RELEASE)
# define ENTITY_PROFILER_ENABLED 
#endif 

#if !defined(_RELEASE) 
# define PHYS_JOB_PROFILER_ENABLED 
#endif 

// optimization if head physics are not needed
//#define PHYS_EXCLUDE_HEAD

enum { NUM_SPUS = 5 }; 

#pragma warning (disable : 4554 4305 4244 4996)
#pragma warning (disable : 6326) //Potential comparison of a constant with another constant

// C6326: potential comparison of a constant with another constant
#define CONSTANT_COMPARISON_OK PREFAST_SUPPRESS_WARNING(6326)
// C6384: dividing sizeof a pointer by another value
#define SIZEOF_ARRAY_OK				 PREFAST_SUPPRESS_WARNING(6384)
// C6246: Local declaration of <variable> hides declaration of same name in outer scope.
#define LOCAL_NAME_OVERRIDE_OK PREFAST_SUPPRESS_WARNING(6246)
// C6201: buffer overrun for <variable>, which is possibly stack allocated: index <name> is out of valid index range <min> to <max> 
#define INDEX_NOT_OUT_OF_RANGE PREFAST_SUPPRESS_WARNING(6201)
// C6385: invalid data: accessing <buffer name>, the readable size is <size1> bytes, but <size2> bytes may be read
#define NO_BUFFER_OVERRUN			 PREFAST_SUPPRESS_WARNING(6385 6386)
// C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead 
#define STACK_ALLOC_OK				 PREFAST_SUPPRESS_WARNING(6255)














inline int StartDynAllocs() { return 0; }
inline int DynAllocsFailed(int iCaller=0) { return 0; }
inline int EndDynAllocs() { return 0; }
inline void SetDynPoolSize(int size) {}
inline int FlushDynPool() { return 1; }
inline int DynAllocsTracked() { return 0; }
inline int SetDynAllocState(void*) { return 0; }
inline void RestoreDynAllocState(int) {}
inline int GetFreeDynSize() { return 0; }
inline int IsPtrDynAlloc(void*) { return 0; }


#include <platform.h>

#ifndef __SPU__
#include <vector>
#include <map>
#include <algorithm>
#include <float.h>

#include "CryThread.h"
#endif

#include "Cry_Math.h"
#include "Cry_XOptimise.h"

#define NO_CRY_STREAM

#ifndef NO_CRY_STREAM
#include "Stream.h"
#else
#ifndef __SPU__
#include "ISystem.h"
#include "ILog.h"
#endif
class CStream {
public:
bool WriteBits(unsigned char *pBits, uint32 nSize) { return true; }
	bool ReadBits(unsigned char *pBits, uint32 nSize) { return true; }
	bool Write(bool b) { return true; }
	bool Write(char c) { return true; }
	bool Write(unsigned char uc) { return true; }
	bool Write(float f) { return true; }
	bool Write(unsigned short us) { return true; }
	bool Write(short s) { return true; }
	bool Write(int i) { return true; }
	bool Write(unsigned int ui) { return true; }
	bool Write(const Vec3 &v) { return true; }
	bool Write(const Ang3 &v) { return true; }
	bool Read(bool &b) { return true; }
	bool Read(char &c) { return true; }
	bool Read(unsigned char &uc) { return true; }
	bool Read(unsigned short &us) { return true; }
	bool Read(short &s) { return true; }
	bool Read(int &i) { return true; }
	bool Read(unsigned int &ui) { return true; }
	bool Read(float &f) { return true; }
	bool Read(Vec3 &v) { return true; }
	bool Read(Ang3 &v) { return true; }
	bool WriteNumberInBits(int n,size_t nSize) { return true; }
	bool WriteNumberInBits(unsigned int n,size_t nSize) { return true; }
	bool ReadNumberInBits(int &n,size_t nSize) { return true; }
	bool ReadNumberInBits(unsigned int &n,size_t nSize) { return true; }
	bool Seek(size_t dwPos = 0) { return true; }
	size_t GetReadPos() { return 0; }
	unsigned char *GetPtr() const { return 0; };
	size_t GetSize() const { return 0; }
	bool SetSize(size_t indwBitSize) { return true; }
};
#endif

#ifdef WIN64
#undef min
#undef max
#endif

//#define PHYS_JOB_SIMULATION
#define USE_SOLVER_JOB
#define USE_CLOTH_JOB
#define USE_ROPE_JOB
#define USE_FEATHERSTONE_JOB
//#define USE_RWI_JOB
#if defined(PS3) || defined(PHYS_JOB_SIMULATION)
#define USE_PHYS_JOBS
#endif
// *Note*: This is now job aware!
#define JOB_LOCAL(...) SPU_LOCAL_FOR_JOBS(__VA_ARGS__)


// Enable rwi debug tracing 
#if !defined(_RELEASE) && defined(USE_RWI_JOB)
//# define RWI_DEBUG_TRACE
#endif 

#if defined(RWI_DEBUG_TRACE)
extern SPU_LOCAL unsigned g_rwi_trace;
# define SET_RWI_TRACE(flags) { if (flags & rwi_debug_trace) { g_rwi_trace |= rwi_debug_trace; } }
# define RESET_RWI_TRACE() { g_rwi_trace &= ~rwi_debug_trace; }
# define RWI_TRACE(format,...) { if (g_rwi_trace & rwi_debug_trace) printf(format, __VA_ARGS__); }
#else
# define SET_RWI_TRACE(flags) {;}
# define RESET_RWI_TRACE() {;}
# define RWI_TRACE(format,...) {;}
#endif 

// Used for rb_intersect to communicate between the main rb_intersect job and
// the auxillary spu executing the actual geom overlap/intersection/unrpojection
// functions. The members prefixed with 'ls' refer to mmio-mapped local store 
// addresses within the respective spus to facilitate spu<->spu communication
struct SAuxillaryJobInfo { 
	volatile int rawSpuId; 
	volatile uintptr_t lsJobFlag; 
	volatile uintptr_t lsBufferOffset; 
	volatile uintptr_t lsDoneFlag; 
	volatile int jobFlag _ALIGN(16);
	volatile int doneFlag _ALIGN(16); 
} _ALIGN(128); 

#ifndef __SPU__
#include "CrySizer.h"










#endif

#ifndef CAFE
#define ENTGRID_2LEVEL
#endif

// TODO: reference additional headers your program requires here
#include "primitives.h"
#include "utils.h"
#include "physinterface.h"

inline DWORD PhysGetCurrentThreadId() { 
#if EMBED_PHYSICS_AS_FIBER && !defined(__SPU__)
	uintptr_t sp = 0; 
#if defined(__SNC__)
	sp = __reg(1);
#else
	asm __volatile__ ("mr %[sp], 1" : [sp] "=r" (sp) : : ); 
#endif
	return (DWORD)((sp+(PHYSICS_STACK_SIZE-1))&~(PHYSICS_STACK_SIZE-1)); 	
#else
	return CryGetCurrentThreadId(); 
#endif
} 



































#define __spu_debug_break
#if !defined(XENON) && MAX_PHYS_THREADS<=1
extern int g_physThreadId;
inline int IsPhysThread() { return iszero((int)PhysGetCurrentThreadId()-g_physThreadId); }
inline void MarkAsPhysThread() { g_physThreadId = PhysGetCurrentThreadId(); }
inline void MarkAsPhysWorkerThread(int*) {}
inline int get_iCaller() { return IsPhysThread()^1; }
inline int get_iCaller_int() { return 0; }
#else // !defined(XENON) && MAX_PHYS_THREADS<=1
TLS_DECLARE(int*,g_pidxPhysThread) 
inline int IsPhysThread() {
	int dummy = 0;
	INT_PTR ptr = (INT_PTR)TLS_GET(INT_PTR, g_pidxPhysThread);
	ptr += (INT_PTR)&dummy-ptr & (ptr-1>>sizeof(INT_PTR)*8-1 ^ ptr>>sizeof(INT_PTR)*8-1);
	return *(int*)ptr; 
}
void MarkAsPhysThread();
void MarkAsPhysWorkerThread(int*);
inline int get_iCaller() {
	int dummy = MAX_PHYS_THREADS;
	INT_PTR ptr = (INT_PTR)TLS_GET(INT_PTR,g_pidxPhysThread);
	ptr += (INT_PTR)&dummy-ptr & (ptr-1>>sizeof(INT_PTR)*8-1 ^ ptr>>sizeof(INT_PTR)*8-1);
	return *(int*)ptr; 
}
#define get_iCaller_int get_iCaller
#endif


#ifdef USE_DYN_POOL
int DynAllocsFailed(int iCaller=get_iCaller());
#endif

#ifndef MAIN_THREAD_NONWORKER
#define FIRST_WORKER_THREAD 1
#else
#define FIRST_WORKER_THREAD 0
#endif

extern volatile int64 g_timeFiber;
#if EMBED_PHYSICS_AS_FIBER
# define YIELD_PHYSFIBER() { int64 timeStart=CryGetTicks(); JobManager::Fiber::YieldFiber(); g_timeFiber += CryGetTicks()-timeStart; }
#else



#   define YIELD_PHYSFIBER() { (void)0; }

#endif 

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__4AA14050_1B79_4A11_9D24_4E209BF87E2C__INCLUDED_)
